PhoneStateListener的使用及其造成的内存泄漏问题分析(转自http://blog.csdn.net/firedancer0089/article/details/60121128) |
您所在的位置:网站首页 › call state › PhoneStateListener的使用及其造成的内存泄漏问题分析(转自http://blog.csdn.net/firedancer0089/article/details/60121128) |
概述
PhoneStateListener是给三方app监听通信状态变化的方法,基本使用如下: [java] view plain copy TelephonyManager mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); PhoneStateListener mPhoneStateListener = new PhoneStateListener(mSubId) { @Override public void onCallStateChanged(int state, String incomingNumber) { ... } }; 首先要创建一个新的PhoneStateListener对象和获取TelephonyManager服务 [java] view plain copy mTelephonyManager.listen( mPhoneStateListener, PhoneStateListener.LISTEN_NONE); mTelephonyManager.listen( mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); 然后使用TelephonyManager注册或者反注册PhoneStateListener,注意注册或者反注册用的是同一个方法,LISTEN_NONE是反注册,其余参数例如LISTEN_CALL_STATE是注册相应事件监听,如需监听多个事件可以用‘|’,例如: [java] view plain copy mTelephonyManager.listenmPhoneStateListener PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR); 监听的事件有多个,监听要实现的回调方法也相应的有多个,例如 PhoneStateListener.LISTEN_CALL_STATE对应 onCallStateChanged(int state, String incomingNumber) 。具体可参见Android sdk。 多卡情况Android5.0之前是单SIM卡,5.0之后加入了多SIM卡机制,PhoneStateListener相应的也可以单独监听某个Phone对象了 [java] view plain copy /** * Create a PhoneStateListener for the Phone using the specified subscription. * This class requires Looper.myLooper() not return null. To supply your * own non-null Looper use PhoneStateListener(int subId, Looper looper) below. * @hide */ public PhoneStateListener(int subId) { this(subId, Looper.myLooper()); } 5.0后多了几个构造函数,参数多了个subId,注意是subId,不是slotId(两者区别可以见我之前写过的文章 subId和slotid)。使用subid就可以区别要监听哪个phone了。吐槽下Android源码中使用subId,因为比较难以理解,5.0之前无论是mtk还是高通的方案中,基本都是使用slotid(要监听卡1或卡2是很常见的,但是要监听iccid为xxxx的sim卡就比较怪了,用户会记得住SIM卡的id或者iccid吗?id是数据库中的递增主键,iccid十几位的数字,用户一般也就记得住卡的号码、卡的运营商和自己把卡插在卡槽1或者卡槽2 这三个信息;还有种情况,如果不插SIM卡,subId和slotid是无法转换的,岂不是卡槽1或者卡槽2分别监听就无法实现了,这种情况下slotid才有意义,subid已经无意义了)。 系统注册代码流程 1.注册服务建立系统服务一般都是起源于SystemServer /frameworks/base/services/java/com/android/server/SystemServer.java [java] view plain copy private void run() { ... startOtherServices(); ... } 调用startOtherServices [java] view plain copy private void startOtherServices() { ... telephonyRegistry = new TelephonyRegistry(context); ServiceManager.addService("telephony.registry", telephonyRegistry); ... } 建立了名称为telephony.registry的服务frameworks/base/services/core/java/com/android/server/TelephonyRegistry.java [java] view plain copy TelephonyRegistry(Context context) { CellLocation location = CellLocation.getEmpty(); mContext = context; mBatteryStats = BatteryStatsService.getService(); // mConnectedApns = new ArrayList(); int numPhones = TelephonyManager.getDefault().getPhoneCount(); if (DBG) log("TelephonyRegistor: ctor numPhones=" + numPhones); mNumPhones = numPhones; mConnectedApns = (ArrayList[]) new ArrayList[numPhones]; mCallState = new int[numPhones]; ... mPreciseDataConnectionState = new PreciseDataConnectionState[numPhones]; for (int i = 0; i |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |